package bsc.war.handler;

import bsc.ejb.entity.DimensionalCut;
import bsc.ejb.entity.Person;
import bsc.ejb.entity.Project;
import bsc.ejb.entity.ScoreCard;
import bsc.ejb.entity.ScoreDomain;
import bsc.ejb.metadata.Colorimetry;
import bsc.ejb.metadata.Comparation;
import bsc.war.delegate.DelegateBSC;
import bsc.war.factory.Factory;
import bsc.war.model.Score;
import bsc.war.model.ScorePojo;
import bsc.war.model.TracerPojo;
import bsc.war.service.BSCUtils;
import bsc.war.service.ScoreCardUtils;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.StringTokenizer;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.collections.ListUtils;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;

/**
 *
 * @author Miguel Angel
 */
public class ShowProjectReport extends AbstractController {

    @Override
    protected ModelAndView handleRequestInternal(
            HttpServletRequest request,
            HttpServletResponse response) throws Exception {
        String modelAndView = "";
        try {
            DelegateBSC delegate = (DelegateBSC) Factory.getBean("DelegateBSC");

            processRequestInternal(request, response, delegate);

            String typeReport = request.getParameter("typeReport");

            if (typeReport.equals("WEB")) {
                modelAndView = "projectReportWeb";
            } else if (typeReport.equals("EXCEL")) {
                response.setContentType("application/vnd.ms-excel"); //Tipo de fichero.
                response.setHeader("Content-Disposition", "attachment;filename=\"report.xls\"");
                modelAndView = "projectReportExcel";
            }

        } catch (Exception e) {
            logger.error("Catched exception", e);
        }
        return new ModelAndView(modelAndView);
    }

    public static void processRequestInternal(HttpServletRequest request,
            HttpServletResponse response, DelegateBSC delegate) {

        //Get the Person
        HttpSession session = request.getSession(true);
        Person person = (Person) session.getAttribute("person");

        //Get selected domains
        Long idScoreDomain = Long.parseLong(request.getParameter("idScoreDomain"));
        List<ScoreDomain> scoreDomains = new ArrayList();

        if (idScoreDomain == -1L) {
            scoreDomains = BSCUtils.getAllPersonScoreDomains(delegate, person);
        } else {
            scoreDomains.add(delegate.findScoreDomain(idScoreDomain));
        }

        //Get date
        Date dateReport = null;
        if (request.getParameter("dateReport") != null) {
            Integer tmpDate[] = new Integer[3];
            StringTokenizer dateTokens = new StringTokenizer(request.getParameter("dateReport"), "/");
            for (int i = 0; i < 3; i++) {
                tmpDate[i] = Integer.parseInt(dateTokens.nextToken());
            }

            dateReport = ScoreCardUtils.generateDate(/*lastDayOfMonth*/tmpDate[0], tmpDate[1], tmpDate[2]);
        }

        //Comparator of the pointer - Basado en los comparador que se estan utilizando
        //List<Comparator> comparators = delegate.findComparator(pointer);
        Comparation comparation = ScoreCardUtils.getSystemComparation(request);


        //Get scorecards of each domian
        java.util.Map<ScoreDomain, List<Project>> scoreDomainProjectsFirst = new HashMap<ScoreDomain, List<Project>>();
        java.util.Map<ScoreDomain, java.util.Map<Project, List<TracerPojo>>> scoreDomainProjectsScores = new HashMap<ScoreDomain, java.util.Map<Project, List<TracerPojo>>>();
        java.util.Map<ScoreDomain, java.util.Map<Project, List<ScoreCard>>> scoreDomainProjectsSCs = new HashMap<ScoreDomain, java.util.Map<Project, List<ScoreCard>>>();
        java.util.Map<ScoreDomain, java.util.Map<ScoreCard, ScorePojo>> scoreDomainScoreCardsScores = new HashMap<ScoreDomain, java.util.Map<ScoreCard, ScorePojo>>();



        for (ScoreDomain scoreDomain : scoreDomains) {

            //Lista de Scorecards de todos los proyectos del domain
            List<ScoreCard> scoreDomainScoreCards = new ArrayList<ScoreCard>();

            //se obtienen todos los proyectos del domain
            List<Project> domainProjectsFirst = ScoreCardUtils.getProjectScoreCards(delegate, scoreDomain.getScoreView().getScoreCard());
            scoreDomainProjectsFirst.put(scoreDomain, domainProjectsFirst);

            //Se obtienen los tracersPojos de cada proyecto del domain
            java.util.Map<Project, List<TracerPojo>> projectsScores = new HashMap<Project, List<TracerPojo>>();
            //Se obtienen los scorecards de cada proyecto del domain
            java.util.Map<Project, List<ScoreCard>> projectsSCs = new HashMap<Project, List<ScoreCard>>();

            for (Project project : domainProjectsFirst) {
                List<TracerPojo> tracersPojo = ScoreCardUtils.getProjectTracer(delegate, project);

                projectsScores.put(project, tracersPojo);

                List<ScoreCard> scoreCards = delegate.findOtherScoreCards(project.getIdScoreCard());
                projectsSCs.put(project, scoreCards);

                scoreDomainScoreCards = ListUtils.union(scoreDomainScoreCards, scoreCards);
            }

            scoreDomainProjectsScores.put(scoreDomain, projectsScores);
            scoreDomainProjectsSCs.put(scoreDomain, projectsSCs);

            //Se obtienen los scores de los scorecards del domain
            java.util.Map<ScoreCard, ScorePojo> scoreCardsScores = new HashMap<ScoreCard, ScorePojo>();
            for (ScoreCard scoreCard : scoreDomainScoreCards) {
                Score score = ScoreCardUtils.calculateScore(delegate, comparation, scoreCard, dateReport);


                ScorePojo scorePojo = (ScorePojo) Factory.getBean("ScorePojo");
                scorePojo.setOutOfDate(score.isOutOfDate());
                scorePojo.setScore(score.getScore());

                //Color
                Colorimetry colorimetry = delegate.findColorimetry(scoreCard, score.getScore());
                String color = "FFFFFF";

                if (scorePojo.isOutOfDate()) {
                    color = "#DEDEDE";
                } else {
                    color = colorimetry.getColor();
                }
                scorePojo.setColor(color);


                scoreCardsScores.put(scoreCard, scorePojo);
            }

            scoreDomainScoreCardsScores.put(scoreDomain, scoreCardsScores);
        }

        request.setAttribute("scoreDomains", scoreDomains);
        request.setAttribute("dateReport", dateReport);
        request.setAttribute("scoreDomainProjectsFirst", scoreDomainProjectsFirst);
        request.setAttribute("scoreDomainProjectsScores", scoreDomainProjectsScores);
        request.setAttribute("scoreDomainProjectsSCs", scoreDomainProjectsSCs);
        request.setAttribute("scoreDomainScoreCardsScores", scoreDomainScoreCardsScores);



        //Update members of all dimensional cuts
        //List of all DimensionalCuts
        List<DimensionalCut> dimensionalCuts = ScoreCardUtils.getDimensionalCuts(request, delegate);
        //Se obtiene los strings de los cuts
        java.util.Map<DimensionalCut, String> dimensionalCutsMembers = ScoreCardUtils.getDimensionalCutsMembersStrings(request, delegate, dimensionalCuts);

        request.setAttribute("dimensionalCutsMembers", dimensionalCutsMembers);


        //Update all the information for recursive


    }
}
